package org.itboys.mobile.service.mysql.mobile.wallet;

import org.itboys.commons.ErrorException;
import org.itboys.commons.utils.tools.ListUtil;
import org.itboys.mobile.common.SundayCommonConstants;
import org.itboys.mobile.dao.wallet.PearlWalletConsumRecordMapper;
import org.itboys.mobile.dao.wallet.PearlWalletMoneyProductMapper;
import org.itboys.mobile.dao.wallet.PearlWalletWithdrawRecordMapper;
import org.itboys.mobile.entity.mongo.PearlAccount;
import org.itboys.mobile.entity.mongo.SundayMember;
import org.itboys.mobile.entity.mysql.wallet.PearlWallet;
import org.itboys.mobile.entity.mysql.wallet.PearlWalletConsumeRecord;
import org.itboys.mobile.entity.mysql.wallet.PearlWalletMoneyProduct;
import org.itboys.mobile.entity.mysql.wallet.PearlWalletWithdrawRecord;
import org.itboys.mobile.service.mongo.mobile.PearlAccountService;
import org.itboys.mobile.service.mongo.mobile.SundayMobileMemberService;
import org.itboys.mongodb.service.BaseMySqlService;
import org.itboys.param.PageResult;
import org.itboys.param.ParamUtil;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created on 2017/9/27.
 * @author 朱坤涛
 */
@Service
public class PearlWalletService extends BaseMySqlService<PearlWallet> {
    @Autowired
    private PearlWalletConsumRecordMapper walletConsumRecordMapper;
    @Autowired
    private PearlWalletMoneyProductMapper walletMoneyProductMapper;
    @Autowired
    private SundayMobileMemberService memberService;
    @Autowired
    private PearlAccountService accountService;
    @Autowired
    private PearlWalletWithdrawRecordMapper withdrawRecordMapper;
    /**
     * 查找用户钱包（收益主表）
     *
     */
    @Transactional
    public PearlWallet findOne(Long memberId){
        Map<String,Object> param = new HashMap<>();
        param.put("memberId",memberId);
        PearlWallet wallet=null;
        List<PearlWallet> wallets = super.select(param);
        if (ListUtil.isNotNull(wallets)){
            wallet = wallets.get(0);
        }else {
            wallet = new PearlWallet(memberId);
            super.insert(wallet);
        }
        return wallet;
    }

    //生成交易记录
    @Transactional
    public  String generateRecord(Long memberId, Integer type, String orderNo, BigDecimal payAmount, List<PearlWalletConsumeRecord> walletRecords,String out_trade_no){
        //查询用户的钱包主表
        PearlWallet wallet = findOne(memberId);
        Double thisAmount = 0.00; //本次交易金额
        /**
         * 1.充值创建订单时，已经写入了充值记录
         * 2.此方法是充值支付成功后 ，使充值记录生效
         */
        if (type== SundayCommonConstants.income_record_type_charge){
            //更改充值记录状态
            for (PearlWalletConsumeRecord walletRecord:walletRecords){
                walletRecord.setStatus(1);
                walletRecord.setRemark(walletRecord.getRemark()+out_trade_no);
                walletConsumRecordMapper.update(walletRecord);
            }
            //更新钱包主表
            BigDecimal amount = new BigDecimal(thisAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
            wallet.setTotalRevenue(wallet.getAbleRevenue().add(amount));
            wallet.setAbleRevenue(wallet.getAbleRevenue().add(amount));
            super.update(wallet);

            //消费减扣
        }else if (type==SundayCommonConstants.income_record_type_consume){
            logger.info("一开始生成余额交易记录");
            thisAmount = payAmount.doubleValue()*(-1);
            BigDecimal amount = new BigDecimal(thisAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
            //生成记录
            PearlWalletConsumeRecord walletRecord = new PearlWalletConsumeRecord(memberId,wallet.getMemberId(),amount,wallet.getAbleRevenue(),SundayCommonConstants.income_record_type_consume,1,"商城消费，订单编号："+orderNo);
            walletConsumRecordMapper.insert(walletRecord);
            logger.info("-当前余额-"+wallet.getAbleRevenue()+"当前交易金额="+amount);
            //更改钱包（收益主表）
            wallet.setAbleRevenue(wallet.getAbleRevenue().add(amount));
            wallet.setFrozenRevenue(wallet.getFrozenRevenue().subtract(amount));
            logger.info("-交易后余额-"+wallet.getAbleRevenue());
            super.update(wallet);
            //系统返还
        }else if (type== SundayCommonConstants.income_record_type_cancel){
            BigDecimal amount = new BigDecimal(thisAmount).setScale(2,BigDecimal.ROUND_HALF_UP);
            //生成记录
            PearlWalletConsumeRecord walletRecord = new PearlWalletConsumeRecord(
                    memberId,wallet.getMemberId(),amount,wallet.getAbleRevenue(),SundayCommonConstants.income_record_type_cancel,1,"订单取消，订单编号："+orderNo
            );
            walletConsumRecordMapper.insert(walletRecord);
            //更改钱包（收益主表）
            wallet.setAbleRevenue(wallet.getAbleRevenue().add(amount));
            wallet.setFrozenRevenue(wallet.getAbleRevenue().subtract(amount));
            super.update(wallet);
        }
        return null;
        }
        //获取充值产品
    public List<Map<String,Object>> getProduct(Long memberId){
        Map<String,Object> param = new HashMap<>();
        List<PearlWalletMoneyProduct> products = walletMoneyProductMapper.select(param);
        List<Map<String,Object>> results = new ArrayList<>();
        for (PearlWalletMoneyProduct product:products){
            Map<String,Object>  result  = new HashMap<String,Object>();
            result.put("id",product.getId());
            result.put("baseAmount",product.getBaseAmount());
            result.put("freeAmount",product.getFreeAmount());
            result.put("totalAmount",product.getBaseAmount().add(product.getFreeAmount()));
            results.add(result);
        }
        return results;
    }

    //充值创建订单
    public Map<String,Object> createOrder(Long memberId, Long productId){
        //准备返还结果
        Map<String,Object> result = new HashMap<>();
        String orderIds = "";
        PearlWallet wallet = findOne(memberId);
        //查询充值产品
        PearlWalletMoneyProduct walletMoneyProduct = walletMoneyProductMapper.find(productId);
        //充值金额
        PearlWalletConsumeRecord walletRecord_charge = new PearlWalletConsumeRecord(
             memberId,wallet.getMemberId(),walletMoneyProduct.getBaseAmount(),
             wallet.getAbleRevenue(),SundayCommonConstants.income_record_type_charge,0,"余额充值，充值编号：");
        walletConsumRecordMapper.insert(walletRecord_charge);
        orderIds += walletRecord_charge.getId()+",";

        //赠送金额
        PearlWalletConsumeRecord wallletRecord_charge_free = new PearlWalletConsumeRecord(memberId,wallet.getId(),walletMoneyProduct.getFreeAmount(),
                wallet.getAbleRevenue(),SundayCommonConstants.income_record_type_free,0,"充值赠送，充值编号：");
        walletConsumRecordMapper.insert(wallletRecord_charge_free);
        orderIds += wallletRecord_charge_free.getId();
        result.put("payAmount",walletRecord_charge.getAmount().setScale(2,BigDecimal.ROUND_HALF_UP));//本次付款金额
        result.put("orderIds",orderIds);
        result.put("isNeedToPay",1);//订单是否需要支付
        result.put("type",2);//余额充值
        result.put("info","isNeedToPay标识是否需要支付。0否，1是。type是标识支付订单类型，1是订单，2是余额充值");
        return result;
    }
    /**
     *获取交易记录
     * @param request
     * @param memberId
     */
    public  List<Map<String,Object>> getRecords(HttpServletRequest request, Long memberId){
        List<Map<String,Object>> results = new ArrayList<Map<String,Object>>();
        Map<String,Object>  param = ParamUtil.packageMysqlPageParam(request,"remark","type");
        param.put("memberId",memberId);
        param.put("status",1);
        List<PearlWalletConsumeRecord> walletConsumeRecords=walletConsumRecordMapper.select(param);
        for(PearlWalletConsumeRecord walletRecord:walletConsumeRecords){
            Map<String,Object>  result  = new HashMap<String,Object>();
            result.put("id",walletRecord.getId());
            result.put("amount",walletRecord.getAmount());
            result.put("type",walletRecord.getType());
            result.put("typeStr",walletRecord.getTypeStr());
            result.put("remark",walletRecord.getRemark());
            result.put("createTime",walletRecord.getCreateTime());
            result.put("createDate",walletRecord.getCreateDate());
            results.add(result);
        }
        return results;
    }


    /**
     * 新增提现功能
     * @author 朱坤涛
     * 时间：2017/10/12 PM 17:40
     */

    //申请提现
    public void applyWithdraw(Long memberId,BigDecimal applyAmount,Long accountId){
        SundayMember member = memberService.getById(memberId);
        //找到用户的收益主表
        PearlWallet wallet = findOne(memberId);
        if (applyAmount.compareTo(wallet.getAbleRevenue())==1){
            throw new ErrorException("当前可提现金为："+wallet.getAbleRevenue());
        }

        PearlWalletWithdrawRecord withdrawRecord = new PearlWalletWithdrawRecord();
        withdrawRecord.setApplyAmount(applyAmount);
        PearlWallet pearlWallet = new PearlWallet();
        pearlWallet.setAbleRevenue(wallet.getAbleRevenue());
        withdrawRecord.setMemberId(memberId);
        withdrawRecord.setStatus(SundayCommonConstants.INCOME_YSQ);
        PearlAccount account = accountService.getById(accountId);
        withdrawRecord.setBank(account.getBank());
        withdrawRecord.setName(account.getName());
        withdrawRecord.setAccount(account.getAccount());
        //收益主表里的可用金额减去本次提现金额
        wallet.setAbleRevenue(wallet.getFrozenRevenue().subtract(applyAmount));
        //保存提现记录
        withdrawRecordMapper.insert(withdrawRecord);
        //更新钱包收益
        super.update(wallet);
    }
    //检查当前申请z状态是否可操作
    public PearlWalletWithdrawRecord checkWalletWithDrawSatus(Long whithDrawId,Integer withDrawStatus){
        PearlWalletWithdrawRecord withdrawRecord = withdrawRecordMapper.find(whithDrawId);
        if (withdrawRecord.getStatus()!=withDrawStatus){
            throw new ErrorException("请勿重复操作");
        }
        return withdrawRecord;
    }
    //同意申请
    public void agreeApply(Long whithDrawId ,String payNo){
        PearlWalletWithdrawRecord withdrawRecord = checkWalletWithDrawSatus(whithDrawId,SundayCommonConstants.INCOME_YSQ);
        //更新提现记录状态
        withdrawRecord.setPayNo(org.apache.commons.lang.StringUtils.isNotEmpty(payNo)?payNo:String.valueOf(new Date().getTime()));
        withdrawRecord.setStatus(SundayCommonConstants.INCOME_YTG);
        withdrawRecordMapper.update(withdrawRecord);
    }

    //拒绝申请
    public void refuseApply(Long withDrawId){
        PearlWalletWithdrawRecord withdrawRecord = checkWalletWithDrawSatus(withDrawId,SundayCommonConstants.INCOME_YSQ);
        //更改提现记录状态
        withdrawRecord.setStatus(SundayCommonConstants.INCOME_YBH);
        withdrawRecordMapper.update(withdrawRecord);
        PearlWallet wallet = findOne(withdrawRecord.getMemberId());
        wallet.setAbleRevenue(wallet.getAbleRevenue().add(withdrawRecord.getApplyAmount()));
    }

    //获取全部提现记录
    public PageResult<PearlWalletWithdrawRecord> getAllWithDrawRecord(HttpServletRequest request){
        Map<String,Object> params = ParamUtil.packageMongoExactParam(request,"status");
        List<PearlWalletWithdrawRecord> allWithdraw = withdrawRecordMapper.select(params);
        Serializable counmtSer = withdrawRecordMapper.count(params);
        Long count = counmtSer ==null?0L:Long.valueOf(counmtSer.toString());
        List<Long> memberIds = new ArrayList<>();
        for (PearlWalletWithdrawRecord withdraw:allWithdraw){
            memberIds.add(withdraw.getMemberId());
        }
        List<SundayMember> members = new ArrayList<>();
        if (ListUtil.isNotNull(memberIds)){
            Map<String,Object> param2 = new HashMap<>();
            param2.put("id in",memberIds);
            members = memberService.list(param2);
        }
            return new PageResult<PearlWalletWithdrawRecord>(allWithdraw,count);

    }

    //获取某人的提现记录
    public PageResult<PearlWalletWithdrawRecord> getWithDrawRecord(HttpServletRequest request,Long memberId){
        Map<String,Object> param = ParamUtil.packageMongoExactParam(request,"");
        param.put("member",memberId);
        List<PearlWalletWithdrawRecord> Withdraws = withdrawRecordMapper.select(param);
        SundayMember member = memberService.getById(memberId);
        Serializable countSer = withdrawRecordMapper.count(param);
        Long count = countSer!=null?Long.valueOf(countSer.toString()):0L;
        return new PageResult<PearlWalletWithdrawRecord>(Withdraws,count);
    }

}